package cn.springbook.common.core.config.serializer;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;
import java.lang.reflect.Type;

@JacksonStdImpl
public class LongToStringSerializer
        extends StdSerializer<Long> {
    public final static LongToStringSerializer instance = new LongToStringSerializer();

    public LongToStringSerializer() {
        super(Long.class);
    }

    @Override
    public boolean isEmpty(SerializerProvider prov, Long value) {
        if (value == null) {
            return true;
        }
        String str = value.toString();
        return str.isEmpty();
    }

    @Override
    public void serialize(Long value, JsonGenerator gen, SerializerProvider provider)
            throws IOException {
        /*
         * 大于16位才返回字符串
         * 否则返回number
         * 主要针对前端格式化JSON数据时
         * 大于16位的数据会丢失精度 导致ID不匹配不到
         * 16位以下为正常，主要用于返回时间戳
         */
        if (value >= 100000000000000000L) {
            gen.writeString(value.toString());
        } else {
            gen.writeNumber(value);
        }
    }

    @Override
    public void serializeWithType(Long value, JsonGenerator gen, SerializerProvider provider,
                                  TypeSerializer typeSer)
            throws IOException {
        typeSer.writeTypePrefixForScalar(value, gen);
        serialize(value, gen, provider);
        typeSer.writeTypeSuffixForScalar(value, gen);
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
        return createSchemaNode("string", true);
    }

    @Override
    public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType typeHint) throws JsonMappingException {
        visitStringFormat(visitor, typeHint);
    }
}
